<?php


class hijreeConvertor {

	var $ac_date = array(
		'year' => "",
		'month' => "",
		'monthname' => "",
		'day' => "",
		'dayname' => ""
	);
	var $ac_date_g = array(
		'year' => "",
		'month' => "",
		'monthname' => "",
		'day' => "",
		'dayname' => ""
	);
	
    var $year;
	var $month;
	var $day;
	var $monthname;
	var $dayname;

	var $julianday;

	var $AC_Adaynames = array(
        0 => "",
        1 => "",
        2 => "",
        3 => "",  
        4 => "",
        5 => "",
        6 => ""
    );
	var $AC_Gdaynames = array(
        '0' => "",
        '1' => "",
        '2' => "",
        '3' => "",
        '4' => "",
        '5' => "",
        '6' => ""
    );
	var $AC_AMonthName = array(
	     '1' => "1",
		 '2' => "2",
		 '3' => "3",
		 '4' => "4",
		 '5' => "5",
		 '6' => "6",
		 '7' => "7",
		 '8' => "8",
		 '9' => "9",
		 '10' => "10",
		 '11' => "11",
		 '12' => "12"
	);   

  /*
		Returns True if is an islamic Leap Year
		@param $ayear : a year !==0.
  */
   function IslamicLeapYear($aYear)
   {
		if ((((11 * $aYear) + 14) % 30) < 11)
			return true;
		else 
			return false;   
   }

  /*
		Returns Last day in month during year on the Islamic calendar.
		@param $ayear : a year !==0.
  */
   function LastDayOfIslamicMonth ($Year, $aMonth)
   {
		if ((($aMonth % 2) == 1) or (($aMonth == 12) and IslamicLeapYear($aYear)))
			return 30;
		else
			return 29;
   }
   
   /*
      Constructs a day with a given year, month, and day.
      @param aYear a year !== 0
      @param aMonth a month between 1 and 12
      @param aDate a date between 1 and 31
   */
   function Ac_Day($aYear, $aMonth, $aDate)
   {
		$this->year  = $aYear;
		$this->month = $aMonth;
		$this->acdate  = $aDate;
   }

   /*
	  Convert from Georgian date to Islamic date.
      @param GYear a year !== 0
      @param GMonth a month between 1 and 12
      @param GDate a date between 1 and 31
   */
   function GregorianToIslamic($GYear, $GMonth, $GDay)
   {
		$y = $GYear;   
		$m = $GMonth;
		$d = $GDay;
		if (( $y > 1582 ) || (( $y == 1582 ) && ( $m > 10 )) || (( $y == 1582 ) && ( $m == 10 ) && ( $d > 14 ))) 
		{
			$jd = (int)(( 1461 * ( $y + 4800 + (int)(( $m - 14 ) / 12 )))/ 4) + (int)(( 367 * ( $m - 2 - 12 * ((int)(( $m - 14 ) / 12)))) / 12) - (int)(( 3 * ((int)(( $y + 4900+ (int)(( $m - 14) / 12) ) / 100))) / 4)+ $d - 32075;
		} else {
			$jd = 367 * $y - (int)(( 7 * ( $y + 5001 + (int)(( $m - 9 ) / 7))) / 4) + (int)(( 275 * $m) / 9) + $d + 1729777;
		}
		$this->julianday = $jd;
		$this->ac_date["dayname"] = $this->Ac_getDayName( $jd % 7 );
		$l = $jd - 1948440 + 10632;
		$n = (int)(( $l - 1 ) / 10631);
		$l = $l - 10631 * $n + 354;
		$j = ( (int)(( 10985 - $l ) / 5316)) * ( (int)(( 50 * $l) / 17719)) + ( (int)( $l / 5670 )) * ( (int)(( 43 * $l ) / 15238 ));
		$l = $l - ( (int)(( 30 - $j ) / 15 )) * ( (int)(( 17719 * $j ) / 50)) - ( (int)( $j / 16 )) * ( (int)(( 15238 * $j ) / 43 )) + 29;
		$m = (int)(( 24 * $l ) / 709 );
		$d = $l - (int)(( 709 * $m ) / 24);
		$y = 30 * $n + $j - 30;
		
		$this->ac_date['year'] = $y;
		$this->ac_date['month'] = $m;
		$this->ac_date['day'] = $d;
		$this->ac_date['monthname'] = $this->Ac_getMonthName($m);
		
		return $this->ac_date;
   }

   /**
    * convert Gregorian time to related hijree date as a string
    * @param type $time
    * @return string
    */
   function GregorianToIslamic2($time)
   {
       $GYear = date('Y', $time);
       $GMonth= date('m', $time);
       $GDay  = date('d', $time);
       
       $h_date_arr = $this->GregorianToIslamic($GYear, $GMonth, $GDay);
       
       return $h_date_arr['year'].'-'.$h_date_arr['month'].'-'.$h_date_arr['day'];
   }
   /*
	  Convert from Islamic date to Georgian date.
      @param IYear a year !== 0
      @param IMonth a month between 1 and 12
      @param IDate a date between 1 and 31
   */
   function IslamicToGregorian($IYear, $IMonth, $IDay)
   {
		$y = $IYear;   
		$m = $IMonth;
		$d = $IDay;
		
		$jd = (int)((11*$y+3)/30)+354*$y+30*$m-(int)(($m-1)/2)+$d+1948440-385;
//		$jd = (int)((11*$y+3)/30)+354*y+30*$m-(int)(($m-1)/2)+$d+1948440-385;
		$this->julianday = $jd;
		$this->ac_date_g[dayname] = $this->Ac_getGDayName( $jd % 7 );
		if ($jd> 2299160 )
		{
			$l=$jd+68569;
			$n=(int)((4*$l)/146097);
			$l=$l-(int)((146097*$n+3)/4);
			$i=(int)((4000*($l+1))/1461001);
			$l=$l-(int)((1461*$i)/4)+31;
			$j=(int)((80*$l)/2447);
			$d=$l-(int)((2447*$j)/80);
			$l=(int)($j/11);
			$m=$j+2-12*$l;
			$y=100*($n-49)+$i+$l;
		} else {
			$j=$jd+1402;
			$k=(int)(($j-1)/1461);
			$l=$j-1461*$k;
			$n=(int)(($l-1)/365)-(int)($l/1461);
			$i=$l-365*$n+30;
			$j=(int)((80*$i)/2447);
			$d=$i-(int)((2447*$j)/80);
			$i=(int)($j/11);
			$m=$j+2-12*$i;
			$y=4*$k+$n+$i-4716;
		}

		$this->ac_date_g[day] = $d;
		$this->ac_date_g[month] = $m;
		$this->ac_date_g[year] = $y;
		$this->ac_date_g[monthname] = $this->Ac_getGMonthName($m);
		
		return $this->ac_date_g;
   }

   /**
      Returns the Julian day 
      @return the year
   */
   function Ac_getJulianDay()
   {
		return $this->julianday;
   }
   
   /**
      Returns the year of this day
      @return the year
   */
   function Ac_getYear()
   {
		return $this->year;
   }

   /**
      Returns the month of this day
      @return the month
   */
   function Ac_getMonth()
   {
		return $this->month;   
   }

   /**
      Returns the name of the day
      @return the day name
   */
   function Ac_getDayName($aDay)
   {
		switch ($aDay)
		{
			case 0: return $this->AC_Adaynames[0];
			break;

			case 1: return $this->AC_Adaynames[1];
			break;

			case 2: return $this->AC_Adaynames[2];
			break;
			
			case 3: return $this->AC_Adaynames[3];
			break;
			
			case 4: return $this->AC_Adaynames[4];
			break;
			
			case 5: return $this->AC_Adaynames[5];
			break;
			
			case 6: return $this->AC_Adaynames[6];
			break;
		}
   }

   /**
      Returns the English name of the day
      @return the day name
   */
   function Ac_getGDayName($aDay)
   {
		switch ($aDay)
		{
			case 0: return $this->AC_Gdaynames[0];
			break;

			case 1: return $this->AC_Gdaynames[1];
			break;

			case 2: return $this->AC_Gdaynames[2];
			break;
			
			case 3: return $this->AC_Gdaynames[3];
			break;
			
			case 4: return $this->AC_Gdaynames[4];
			break;
			
			case 5: return $this->AC_Gdaynames[5];
			break;
			
			case 6: return $this->AC_Gdaynames[6];
			break;
		}
   }
   
   /**
      Returns the name of the islamic month
      @return the day name
   */
   function Ac_getMonthName($aMonth)
   {
		switch ($aMonth)
		{
			case 1: return $this->AC_AMonthName[1];
			break;

			case 2: return $this->AC_AMonthName[2];
			break;
			
			case 3: return $this->AC_AMonthName[3];
			break;
			
			case 4: return $this->AC_AMonthName[4];
			break;
			
			case 5: return $this->AC_AMonthName[5];
			break;
			
			case 6: return $this->AC_AMonthName[6];
			break;
			
			case 7: return $this->AC_AMonthName[7];
			break;
			
			case 8: return $this->AC_AMonthName[8];
			break;
			
			case 9: return $this->AC_AMonthName[9];
			break;
			
			case 10: return $this->AC_AMonthName[10];
			break;
			
			case 11: return $this->AC_AMonthName[11];
			break;

			case 12: return $this->AC_AMonthName[12];
			break;
		}
   }
   

   /**
      Returns the month number
      @return the day name
   */
   function Ac_getGMonthName($aMonth)
   {
		switch ($aMonth)
		{
			case 1: return 1;
			break;

			case 2: return 2;
			break;
			
			case 3: return 3;
			break;
			
			case 4: return 4;
			break;
			
			case 5: return 5;
			break;
			
			case 6: return 6;
			break;
			
			case 7: return 7;
			break;
			
			case 8: return 8;
			break;
			
			case 9: return 9;
			break;
			
			case 10: return 10;
			break;
			
			case 11: return 11;
			break;

			case 12: return 12;
			break;
		}
   }
   
   
   /**
      Returns the date of this day
      @return the date
   */
   function Ac_getDate()
   {
		return $this->year;   
   }

   /**
      Returns a day that is a certain number of days away from
      this day
      @param n the number of days, can be negative
      @return a day that is n days away from this one
   */
   function Ac_addDays($n)
   {
   
   }

   /**
      Returns the number of days between this day and another
      day
      @param other the other day
      @return the number of days that this day is away from 
      the other (>0 if this day comes later)
   */
   function Ac_daysFrom($Dayother)
   {
   }
}

/********************************************************************************************/
/********************************************************************************************/



?>